﻿using System.Reflection;
using System.Threading.Tasks;

#nullable disable
namespace BeetleX.XRPC.Clients
{
    public class XRPCSeverInvokeClientDispatch : XRPCClientDispatch
    {
        public ISession Session { get; set; }

        public XRPCServer Server { get; set; }

        protected override object Invoke(MethodInfo targetMethod, object[] args)
        {
            ClientActionHandler clientActionHandler;
            if (!this.Handlers.TryGetValue(targetMethod.Name, out clientActionHandler))
                throw new XRPCException(targetMethod.Name + " action not found!")
                {
                    ErrorCode = 404
                };
            if (!clientActionHandler.IsTaskResult)
                throw new XRPCException("Definition is not supported, please define task with return value!")
                {
                    ErrorCode = 403
                };
            Task<RPCPacket> task = this.Server.SendWait(new RPCPacket()
            {
                Url = clientActionHandler.Url,
                Data = args
            }, this.Session, clientActionHandler.ResponseType);
            IAnyCompletionSource completionSource = clientActionHandler.GetCompletionSource();
            completionSource.WaitResponse(task);
            return (object)completionSource.GetTask();
        }
    }
}
